﻿#include "ServerListModel.h"
#include <QDebug>
#include <QTcpSocket>
#include <QHostAddress>
#include <QThread>
#include <QtCore/QEvent>
#include <QtCore/QtCore>
#include <QtNetwork/QNetworkInterface>
#include <QClipboard>
#include <QGuiApplication>

//#include <QDesktopServices>
#include <QProcess>
//#include <qwindow.h>
//#include <windows.h>

#include <iostream>
#include <future>
#include <chrono>
#include <thread>
#include <vector>

#include <QtConcurrent>


// 自定义事件，检测FTP结果事件
class QPingFtpResultEvent : public QEvent
{
public:
    explicit QPingFtpResultEvent(const QString& ftpIP, int ftpPort, const QString& ftpName);
    ~QPingFtpResultEvent();
public:
    QString ftpIP;
    int ftpPort;
    QString ftpName;
public:
    static int mEventType;

};
int QPingFtpResultEvent::mEventType = QEvent::registerEventType();

QPingFtpResultEvent::QPingFtpResultEvent(const QString& ftpIP, int ftpPort, const QString& ftpName)
    : QEvent(QEvent::Type(mEventType))
    , ftpIP(ftpIP)
    , ftpPort(ftpPort)
    , ftpName(ftpName)
{

}

QPingFtpResultEvent::~QPingFtpResultEvent()
{

}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// 自定义事件，检测FTP所有任务结束
class QPingFtpFinishEvent : public QEvent
{
public:
    explicit QPingFtpFinishEvent();
    ~QPingFtpFinishEvent();
public:
    static int mEventType;

};
int QPingFtpFinishEvent::mEventType = QEvent::registerEventType();

QPingFtpFinishEvent::QPingFtpFinishEvent()
    : QEvent(QEvent::Type(mEventType))
{

}

QPingFtpFinishEvent::~QPingFtpFinishEvent()
{

}


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


ServerListModel *ServerListModel::Singleton()
{
    static ServerListModel * singleton = new ServerListModel();
    return singleton;
}

ServerListModel::ServerListModel(QObject *parent ) : QAbstractListModel(parent)
{
    QVector<quint16> portVec;
    for (quint16 i = 30000; i < 30000+10; ++i)
    {
        portVec << i;
    }

#if 1
    //addServer(tr("192.168.1.2:2121"), tr("ftp://test:123456@192.168.1.3:2121/"));
    //addServer(tr("pc-sina"), tr("https://www.sina.com.cn"));
    //addServer(tr("pc-localhost"), tr("http://127.0.0.1"));
#endif

    //std::vector<std::pair<std::string,std::string>> addrVec;
    //GetLocalAddrQt(addrVec);
    /*for (auto data : addrVec) {
        qDebug() << QString::fromStdString(data);
    }*/

    //std::vector<std::string> ipVec;
    //GetLANIPs(ipVec);


    // 设置最大线程数，在搜索时可以同时更多线程运行
    QThreadPool::globalInstance()->setMaxThreadCount(1024);

}

ServerListModel::~ServerListModel()
{

}

int ServerListModel::rowCount(const QModelIndex &) const
{
    return mServerInfoList.count();
}

QVariant ServerListModel::data(const QModelIndex &index, int role) const
{
    if (index.row() < rowCount())
    {
        switch (role) {
        case ServerNameRole: return mServerInfoList.at(index.row()).serverName;
        case ServerAddrRole: return mServerInfoList.at(index.row()).serverAddr;
        case FtpIPRole: return mServerInfoList.at(index.row()).ftpIP;
        case FtpPortRole: return mServerInfoList.at(index.row()).ftpPort;
        case FtpNameRole: return mServerInfoList.at(index.row()).ftpName;

        default: return QVariant();
        }
    }
    return QVariant();
}

QHash<int, QByteArray> ServerListModel::roleNames() const
{
    static const QHash<int, QByteArray> roles {
        { ServerNameRole, "serverName" },
        { ServerAddrRole, "serverAddr" },
        { FtpIPRole, "ftpIP" },
        { FtpPortRole, "ftpPort" },
        { FtpNameRole, "ftpName" },
    };
    return roles;
}

#if 0
QVariantMap ServerListModel::get(int row) const
{
    const ServerInfo serverInfo = mServerInfoList.value(row);
    return { {"serverName", serverInfo.serverName}
        , {"serverAddr", serverInfo.serverAddr}
        , {"ftpIP", serverInfo.ftpIP}
        , {"ftpPort", serverInfo.ftpPort}
        , {"ftpName", serverInfo.ftpName}
    };
}
#endif

void ServerListModel::addServer(const QString& serverName, const QString& serverAddr, const QString& ftpIP, int ftpPort, const QString& ftpName)
{
    qDebug() << "addServer:" << serverName << ", " << serverAddr;
    for (int row = 0; row < mServerInfoList.count(); ++row)
    {
        if(serverName == mServerInfoList.at(row).serverName
                && serverAddr == mServerInfoList.at(row).serverAddr)
        {
            dataChanged(index(row, 0), index(row, 0), {ServerNameRole, ServerAddrRole});
            return ;
        }
    }

    int row = mServerInfoList.size();
    beginInsertRows(QModelIndex(), row, row);
    mServerInfoList.insert(row, ServerInfo(serverName, serverAddr, ftpIP, ftpPort, ftpName));
    endInsertRows();

}

void ServerListModel::remove(int row)
{
    if (row < 0 || row >= mServerInfoList.count())
    {
        return;
    }
    beginRemoveRows(QModelIndex(), row, row);
    mServerInfoList.removeAt(row);
    endRemoveRows();
}

void ServerListModel::clear()
{
    int count = mServerInfoList.count();
    if(count > 0)
    {
        beginRemoveRows(QModelIndex(), 0, count-1);
        mServerInfoList.clear();
        endRemoveRows();
    }
}

void ServerListModel::pingFtp(QString strIp, int iPort)
{
    //QString strIp = "192.168.1.3";
    //int iPort = 2121;
    //qDebug() << "pingFtp(" << strIp << "," << iPort << ")";

    QTcpSocket socket;
    socket.connectToHost(QHostAddress(strIp), iPort);
    //socket.connectToHost(QHostAddress::LocalHost, 21);
    if (socket.waitForConnected(5000)) {
        qDebug() << "connect success:" << strIp << ":" << iPort;
        if(socket.waitForReadyRead(3000)){
            QByteArray byteArray = socket.readAll();
            qDebug() << "receive data:" << byteArray;
            // "220 SwiFTP 3.2.4 ready\r\n"
            // "220-FileZilla Server version 0.9.43 beta\r\n"
            std::string strData = byteArray.toStdString();
            if(0 == strData.find("220") && strData.size()-2 == strData.rfind("\r\n"))
            {
                qDebug() << "it is a ftp";
                QString ftpName = QString::fromStdString(strData);
                {// 处理，获取服务名称
                    if(ftpName.length() > 3 && ftpName.left(3).compare("220") == 0)
                    {
                        ftpName = ftpName.mid(3);
                    }
                    if(ftpName.length() > 2 && ftpName[0] == '-')
                    {
                        ftpName = ftpName.mid(1);
                    }
                    ftpName = ftpName.replace("ready", "");
                    ftpName = ftpName.trimmed();
                }
                QPingFtpResultEvent * event = new QPingFtpResultEvent(strIp, iPort, ftpName);
                QCoreApplication::postEvent(this, event);
                //this->addServer(QObject::tr("%1:%2").arg(strIp).arg(iPort), QObject::tr("ftp://test:123456@%1:%2/").arg(strIp).arg(iPort));
            }
            else
            {
                qDebug() << "it is not a ftp";
            }
        }
    }
    else {
        //qDebug() << "connect fail:" << strIp << ":" << iPort;
    }
    socket.disconnectFromHost();
    //qDebug() << "pingFtp(" << strIp << "," << iPort << ") end";
    // 线程结束
    --pingFtpThreadCount;
    if(pingFtpThreadCount == 0)
    {// 判断是否全部结束
        QPingFtpFinishEvent * event = new QPingFtpFinishEvent();
        QCoreApplication::postEvent(this, event);
    }
}

void ServerListModel::customEvent(QEvent *event)
{
    if (QPingFtpResultEvent::mEventType == (ushort)event->type())
    {// 识别结果事件
        if (QPingFtpResultEvent * pEvent = static_cast<QPingFtpResultEvent*>(event))
        {
            this->addServer(QObject::tr("%1:%2").arg(pEvent->ftpIP).arg(pEvent->ftpPort)
                            , QObject::tr("ftp://%1:%2/").arg(pEvent->ftpIP).arg(pEvent->ftpPort)
                            , pEvent->ftpIP, pEvent->ftpPort, pEvent->ftpName
                            );
        }
    }
    else if (QPingFtpFinishEvent::mEventType == (ushort)event->type())
    {
        qDebug() <<  tr("收到检测FTP全部线程结束事件");
        emit signalShowMsg(tr("搜索FTP结束"));
    }
}

void ServerListModel::scanServer(int ftpPort)
{
    qDebug() << "scanServer(" << ftpPort << ")";
    this->clear();

    std::vector<std::string> ipVec;
    GetLANIPs(ipVec);   // 获取局域网其他同网段IP地址
    if(ipVec.empty())
    {
        qDebug() << "局域网其他IP地址为空列表";
        return;
    }
    for(size_t i = 0; i < ipVec.size(); ++i)
    {
        ++pingFtpThreadCount;
        qDebug() << "启动连接线程：" << ipVec[i].c_str();
        //std::thread *th = new std::thread(&ServerListModel::pingFtp, this, tr("%1").arg(ipVec[i].c_str()), 2121);
        QFuture<void> future = QtConcurrent::run(this, &ServerListModel::pingFtp, tr("%1").arg(ipVec[i].c_str()), ftpPort);
    }

}

void ServerListModel::openServer(QString ftpIP, int ftpPort, QString userName, QString userPassword)
{
    // ftp://192.168.0.105:2121
    // C:/Windows/explorer.exe
    //QProcess::execute("C:/Windows/explorer.exe", QStringList() << "ftp://test:123456@192.168.0.105:2121/");
    //QProcess::execute("C:/Windows/explorer.exe", QStringList() << "ftp://anonymous@192.168.0.105:2121/");
    //QProcess::execute("C:/Windows/explorer.exe", QStringList() << "ftp://192.168.0.105:2121/");
    //
    //::WinExec("C:/Windows/explorer.exe ftp://192.168.0.105:2121", SW_SHOW);
    //ShellExecuteA(NULL, "open", "explorer.exe", "ftp://192.168.0.105:2121/", "", SW_SHOW );

    if(ftpIP.isEmpty())
    {
        emit signalShowMsg(tr("FTP地址为空"));
        return;
    }
    if(ftpPort <= 0)
    {
        ftpPort = 21;
    }
    QString strAddr = tr("ftp://%1:%2/").arg(ftpIP).arg(ftpPort);
    if(!userName.isEmpty() && !userPassword.isEmpty())
    {
        strAddr = tr("ftp://%1:%2@%3:%4/").arg(userName).arg(userPassword).arg(ftpIP).arg(ftpPort);
    }
    else if(!userName.isEmpty() && userPassword.isEmpty())
    {
        strAddr = tr("ftp://%1@%2:%3/").arg(userName).arg(ftpIP).arg(ftpPort);
    }
    qDebug() << "openServer:" << strAddr;
    int res = QProcess::execute("C:/Windows/explorer.exe", QStringList() << strAddr);
    qDebug() << "execute res:" << res;
    if(res != 0)
    {
        emit signalShowMsg(tr("执行打开命令失败！错误：%1").arg(res));
    }
}

void ServerListModel::ftpAddrToClipboard(QString ftpIP, int ftpPort, QString userName, QString userPassword)
{
    if(ftpIP.isEmpty())
    {
        emit signalShowMsg(tr("FTP地址为空"));
        return;
    }
    if(ftpPort <= 0)
    {
        ftpPort = 21;
    }
    QString strAddr = tr("ftp://%1:%2/").arg(ftpIP).arg(ftpPort);
    if(!userName.isEmpty() && !userPassword.isEmpty())
    {
        strAddr = tr("ftp://%1:%2@%3:%4/").arg(userName).arg(userPassword).arg(ftpIP).arg(ftpPort);
    }
    else if(!userName.isEmpty() && userPassword.isEmpty())
    {
        strAddr = tr("ftp://%1@%2:%3/").arg(userName).arg(ftpIP).arg(ftpPort);
    }
    qDebug() << "ftpAddrToClipboard:" << strAddr;


    QClipboard *clipboard = QGuiApplication::clipboard();
    clipboard->setText(strAddr);
    emit signalShowMsg(tr("地址已经复制到剪切板"));
}

/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void ServerListModel::GetLANIPs(std::vector<std::string>& ipVec)
{
    QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
    foreach(QNetworkInterface interfaceItem, interfaceList)
    {
        //qDebug("#######################################################");
        // 过滤部分无效网卡
        if (!interfaceItem.isValid()
                || !interfaceItem.flags().testFlag(QNetworkInterface::IsUp)
                || !interfaceItem.flags().testFlag(QNetworkInterface::IsRunning)
                || !interfaceItem.flags().testFlag(QNetworkInterface::CanBroadcast)
                || !interfaceItem.flags().testFlag(QNetworkInterface::CanMulticast)
                || interfaceItem.flags().testFlag(QNetworkInterface::IsLoopBack)
                )
        {
            continue;
        }
        // 过滤虚拟网卡 VMware Network Adapter VMnet1  ||  vEthernet
        if (interfaceItem.name().contains("VMware Network Adapter")
                || interfaceItem.humanReadableName().contains("VMware Network Adapter")
                || interfaceItem.name().contains("vEthernet")
                || interfaceItem.humanReadableName().contains("vEthernet")
                )
        {
            continue;
        }

        QList<QNetworkAddressEntry> addressEntryList = interfaceItem.addressEntries();
        foreach(QNetworkAddressEntry addressEntryItem, addressEntryList)
        {
            if (addressEntryItem.ip().protocol() == QAbstractSocket::IPv4Protocol)
            {

                //qDebug() << "------------------------------------------------------------";
                //qDebug() << "Adapter Name:" << interfaceItem.name();
                //qDebug() << "Adapter Address:" << interfaceItem.hardwareAddress();
                //qDebug() << "type:" << interfaceItem.type();
                //qDebug() << "humanReadableName:" << interfaceItem.humanReadableName();
                //qDebug() << "dnsEligibility:" << addressEntryItem.dnsEligibility();
                qDebug() << "IP Address:" << addressEntryItem.ip().toString();
                qDebug() << "IP Mask:" << addressEntryItem.netmask().toString();
                qDebug() << "broadcast:" << addressEntryItem.broadcast().toString();
                qDebug() << "IP prefixLength:" << addressEntryItem.prefixLength();

                // 获取IP地址前缀
                quint32 prefixIp = addressEntryItem.broadcast().toIPv4Address() & addressEntryItem.netmask().toIPv4Address();
                //quint32 prefixIp = addressEntryItem.ip().toIPv4Address();
                /*for(int i = 0; i < 32 - addressEntryItem.prefixLength(); ++i)
                {
                    prefixIp &= ~(0x01 << i);
                }
                */
                //prefixIp = prefixIp >> (32 - addressEntryItem.prefixLength());
                //prefixIp = prefixIp << (32 - addressEntryItem.prefixLength());
                qDebug() << "prefixIp:" << QHostAddress(prefixIp).toString();

                for(int i = 1; i < ~addressEntryItem.netmask().toIPv4Address(); ++i)
                {
                    if(QHostAddress(prefixIp + i).isInSubnet(addressEntryItem.ip(), addressEntryItem.prefixLength())
                            && !QHostAddress(prefixIp + i).isBroadcast()
                            && !QHostAddress(prefixIp + i).isLinkLocal()
                            && !QHostAddress(prefixIp + i).isLoopback()
                            && !QHostAddress(prefixIp + i).isMulticast())
                    {
                        ipVec.push_back(QHostAddress(prefixIp + i).toString().toStdString());
                        //qDebug() << "Subnet ip:" << QHostAddress(prefixIp + i).toString();
                    }
                }


                /*qDebug() << addressEntryItem.ip().toString()
                    << " protocol:" << addressEntryItem.ip().protocol()
                    << " isLoopback:" << addressEntryItem.ip().isLoopback()
                    << " isGlobal:" << addressEntryItem.ip().isGlobal()
                    << " isLinkLocal:" << addressEntryItem.ip().isLinkLocal()
                    << " isSiteLocal:" << addressEntryItem.ip().isSiteLocal()
                    << " isUniqueLocalUnicast:" << addressEntryItem.ip().isUniqueLocalUnicast()
                    << " isMulticast:" << addressEntryItem.ip().isMulticast()
                    << " isBroadcast:" << addressEntryItem.ip().isBroadcast()
                    << " scopeId:" << addressEntryItem.ip().scopeId();*/

            }
        }
    }
}
void ServerListModel::GetLocalAddrQt(std::vector<std::pair<std::string,std::string>>& addrVec)
{
    QList<QNetworkInterface> interfaceList = QNetworkInterface::allInterfaces();
    foreach(QNetworkInterface interfaceItem, interfaceList)
    {
        //qDebug("#######################################################");
        // 过滤部分无效网卡
        if (!interfaceItem.isValid()
                || !interfaceItem.flags().testFlag(QNetworkInterface::IsUp)
                || !interfaceItem.flags().testFlag(QNetworkInterface::IsRunning)
                || !interfaceItem.flags().testFlag(QNetworkInterface::CanBroadcast)
                || !interfaceItem.flags().testFlag(QNetworkInterface::CanMulticast)
                || interfaceItem.flags().testFlag(QNetworkInterface::IsLoopBack)
                )
        {
            continue;
        }
        // 过滤虚拟网卡 VMware Network Adapter VMnet1  ||  vEthernet
        if (interfaceItem.name().contains("VMware Network Adapter")
                || interfaceItem.humanReadableName().contains("VMware Network Adapter")
                || interfaceItem.name().contains("vEthernet")
                || interfaceItem.humanReadableName().contains("vEthernet")
                )
        {
            continue;
        }

        QList<QNetworkAddressEntry> addressEntryList = interfaceItem.addressEntries();
        foreach(QNetworkAddressEntry addressEntryItem, addressEntryList)
        {
            if (addressEntryItem.ip().protocol() == QAbstractSocket::IPv4Protocol)
            {

                //qDebug() << "------------------------------------------------------------";
                //qDebug() << "Adapter Name:" << interfaceItem.name();
                //qDebug() << "Adapter Address:" << interfaceItem.hardwareAddress();
                //qDebug() << "type:" << interfaceItem.type();
                //qDebug() << "humanReadableName:" << interfaceItem.humanReadableName();
                //qDebug() << "dnsEligibility:" << addressEntryItem.dnsEligibility();
                qDebug() << "IP Address:" << addressEntryItem.ip().toString();
                qDebug() << "IP Mask:" << addressEntryItem.netmask().toString();
                qDebug() << "broadcast:" << addressEntryItem.broadcast().toString();
                qDebug() << "IP prefixLength:" << addressEntryItem.prefixLength();

                /*qDebug() << addressEntryItem.ip().toString()
                    << " protocol:" << addressEntryItem.ip().protocol()
                    << " isLoopback:" << addressEntryItem.ip().isLoopback()
                    << " isGlobal:" << addressEntryItem.ip().isGlobal()
                    << " isLinkLocal:" << addressEntryItem.ip().isLinkLocal()
                    << " isSiteLocal:" << addressEntryItem.ip().isSiteLocal()
                    << " isUniqueLocalUnicast:" << addressEntryItem.ip().isUniqueLocalUnicast()
                    << " isMulticast:" << addressEntryItem.ip().isMulticast()
                    << " isBroadcast:" << addressEntryItem.ip().isBroadcast()
                    << " scopeId:" << addressEntryItem.ip().scopeId();*/

                addrVec.push_back(std::pair<std::string,std::string>(addressEntryItem.ip().toString().toStdString(), addressEntryItem.netmask().toString().toStdString()));
            }
        }
    }
}

#if 0
#include <qwindow.h>
#include <Windows.h>
#include <IPTypes.h>
#include <TlHelp32.h>
//#include <WinSock2.h>
#include <iphlpapi.h>
#include <shellapi.h>
// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "ws2_32.lib")
void ServerListModel::GetLocalAddrWindows(std::vector<std::string>& addrVec)
{
    ULONG Family = AF_UNSPEC;
    ULONG Flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS;
    PIP_ADAPTER_ADDRESSES AdapterAddresses = NULL;
    ULONG SizePointer = 0;
    ULONG ulRes = GetAdaptersAddresses(Family, Flags, NULL, AdapterAddresses, &SizePointer);
    if (ERROR_BUFFER_OVERFLOW == ulRes)
    {
        AdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(static_cast<size_t>(SizePointer));
        if (ERROR_SUCCESS == GetAdaptersAddresses(Family, Flags, NULL, AdapterAddresses, &SizePointer))
        {
            for (PIP_ADAPTER_ADDRESSES pCurrAddresses = AdapterAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next)
            {
                //qDebug() << "##############################################################";
                if (pCurrAddresses->OperStatus != IfOperStatusUp)
                {// 跳过不可用的网卡
                    continue;
                }
                if (pCurrAddresses->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
                {
                    //qDebug() << "本地循环网络";
                    continue;
                }
                if (pCurrAddresses->PhysicalAddressLength != 6)
                {// 127.0.0.1没有mac
                    continue;
                }
                if (!pCurrAddresses->FirstGatewayAddress)
                {// 没有默认网关的地址，估计外网不能访问，发现虚拟机的虚拟网卡都没有默认网关
                    continue;
                }
                // 过滤虚拟网卡
                // VMware Network Adapter VMnet1(VMware Virtual Ethernet Adapter for VMnet1)
                // vEthernet(Hyper-V Virtual Ethernet Adapter)
                if (std::wstring(pCurrAddresses->FriendlyName).find(L"VMware Network Adapter") != std::wstring::npos
                        || std::wstring(pCurrAddresses->FriendlyName).find(L"vEthernet") != std::wstring::npos
                        )
                {
                    continue;
                }

                //LogPrintfEx("AdapterName:%s", pCurrAddresses->AdapterName);
                //qDebug() << "DnsSuffix:" << QString::fromWCharArray(pCurrAddresses->DnsSuffix);
                //qDebug() << "Description:" << QString::fromWCharArray(pCurrAddresses->Description);
                //qDebug() << "FriendlyName:" << QString::fromWCharArray(pCurrAddresses->FriendlyName);

                //qDebug() << "Flags:" << pCurrAddresses->Flags;
                if (0 == (pCurrAddresses->Flags & IP_ADAPTER_IPV4_ENABLED))
                {
                    //qDebug() << "不包含IPV4";
                }

                //qDebug() << "IfType:" << pCurrAddresses->IfType;
                if (pCurrAddresses->IfType == IF_TYPE_PROP_VIRTUAL)
                {
                    //qDebug() << "虚拟网络";
                }

                //qDebug() << "OperStatus:" << pCurrAddresses->OperStatus;

                //qDebug() << "ConnectionType" << pCurrAddresses->ConnectionType;

                {// MAC
                    bool isUppercase = true;
                    bool horizontalLine = false;
                    std::wstringstream strMacStream;
                    strMacStream.flags(std::ios::right | std::ios::hex);//| std::ios::showbase );
                    if (isUppercase)
                    {
                        strMacStream.setf(std::ios::uppercase);
                    }
                    else
                    {
                        strMacStream.unsetf(std::ios::uppercase);
                    }
                    strMacStream.width(2);
                    strMacStream.fill('0');
                    for (unsigned int i = 0; i < pCurrAddresses->PhysicalAddressLength; ++i)
                    {
                        strMacStream << (int)pCurrAddresses->PhysicalAddress[i];
                        if (horizontalLine && i != pCurrAddresses->PhysicalAddressLength - 1)
                        {
                            strMacStream << L"-";
                        }
                    }
                    std::wstring strMac = strMacStream.str();
                    //qDebug() << "MAC:" << QString::fromStdWString(strMac);
                }

                // 显示测试函数
                auto funcOutputAdress = [](SOCKET_ADDRESS& Address, char * pstrPrefix) {
                    CHAR IP[128] = { 0 };
                    if (AF_INET == Address.lpSockaddr->sa_family)// IPV4 地址，使用 IPV4 转换
                    {
                        inet_ntop(PF_INET, &((sockaddr_in*)Address.lpSockaddr)->sin_addr, IP, sizeof(IP));
                        //LogPrintfEx("%s:%s", pstrPrefix, IP);
                    }
                    //else if (AF_INET6 == Address.lpSockaddr->sa_family)// IPV6 地址，使用 IPV6 转换
                    //{
                    //	inet_ntop(PF_INET6, &((sockaddr_in6*)Address.lpSockaddr)->sin6_addr, IP, sizeof(IP));
                    //	LogPrintfEx("%s:%s", pstrPrefix, IP);
                    //}
                };
                //单播IP
                for (auto pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next)
                {
                    //funcOutputAdress(pUnicast->Address, "Unicast Address");
                    CHAR IP[128] = { 0 };
                    if (AF_INET == pUnicast->Address.lpSockaddr->sa_family)// IPV4 地址，使用 IPV4 转换
                    {
                        inet_ntop(PF_INET, &((sockaddr_in*)pUnicast->Address.lpSockaddr)->sin_addr, IP, sizeof(IP));
                        //LogPrintfEx("%s:%s", pstrPrefix, IP);
                        addrVec.push_back(IP);
                    }
                }
                /*
                // 任播地址
                for (auto pAnycastAddress = pCurrAddresses->FirstAnycastAddress; pAnycastAddress; pAnycastAddress = pAnycastAddress->Next)
                {
                    funcOutputAdress(pAnycastAddress->Address, "Anycast Address");
                }
                // 广播地址
                for (auto pMulticastAddress = pCurrAddresses->FirstMulticastAddress; pMulticastAddress; pMulticastAddress = pMulticastAddress->Next)
                {
                    funcOutputAdress(pMulticastAddress->Address, "Multicast Address");
                }
                // DNS
                for (auto pDnsServerAddress = pCurrAddresses->FirstDnsServerAddress; pDnsServerAddress; pDnsServerAddress = pDnsServerAddress->Next)
                {
                    funcOutputAdress(pDnsServerAddress->Address, "Dns Server Address");
                }
                // Wins Server Address
                for (auto pWinsServerAddress = pCurrAddresses->FirstWinsServerAddress; pWinsServerAddress; pWinsServerAddress = pWinsServerAddress->Next)
                {
                    funcOutputAdress(pWinsServerAddress->Address, "Wins Server Address");
                }
                // 网关
                for (auto pGatewayAddress = pCurrAddresses->FirstGatewayAddress; pGatewayAddress; pGatewayAddress = pGatewayAddress->Next)
                {
                    funcOutputAdress(pGatewayAddress->Address, "Gateway Address");
                }
                // 适配器前缀
                for (auto pPrefix = pCurrAddresses->FirstPrefix; pPrefix; pPrefix = pPrefix->Next)
                {
                    funcOutputAdress(pPrefix->Address, "Adapter Prefix");
                }
                //DHCP服务器地址
                if (pCurrAddresses->Dhcpv4Server.lpSockaddr)
                {
                    funcOutputAdress(pCurrAddresses->Dhcpv4Server, "Dhcp v4 Server");
                }
                */

            }
        }
        if (AdapterAddresses)
        {
            free(AdapterAddresses);
        }
    }
    return;
}
#endif
